import React, { Children } from 'react';
import _ from 'lodash';

export default class ZrThrottleWrapper extends React.Component {
  throttledMap = new Map(); // 缓存节流函数

  shouldComponentUpdate(nextProps) {
    return nextProps !== this.props;
  }

  componentDidUpdate(prevProps) {
    this.throttledMap = new Map(); // 缓存节流函数
  }

  componentWillUnmount() {
    // 取消所有挂起的节流操作
    this.throttledMap.forEach(throttledFunc => {
      throttledFunc.cancel();
    });
  }

  // 处理异步函数的核心方法
  createThrottledHandler = (originalHandler, throttleTime, throttleOptions) => {
    // 创建基础节流函数
    const throttledFunc = _.throttle(
      (...args) => {
        const result = originalHandler(...args);

        // 处理 Promise 返回值
        if (result instanceof Promise) {
          return new Promise((resolve, reject) => {
            result
              .then(resolve)
              .catch(reject)
              .finally(() => {
                // 确保节流计时器在 Promise 完成后才重置
                throttledFunc.flush();
              });
          });
        }

        return result;
      },
      throttleTime,
      throttleOptions
    );

    return throttledFunc;
  };

  render() {
    const {
      children,
      throttleTime = 300,
      throttleOptions = { leading: true, trailing: false },
      events = ['onClick', 'onTap'],
    } = this.props;

    return Children.map(children, (child, index) => {
      if (!React.isValidElement(child)) return child;

      const propsNm = Object.keys(child.props);
      const newEventObj = {};

      propsNm.forEach((eventName) => {
        if (
          events.includes(eventName) &&
          typeof child.props[eventName] === 'function'
        ) {
          // 创建唯一缓存键
          const cacheKey = `${child.type.name || 'unknown'}-${eventName}-${index}`;

          // 获取或创建节流函数
          if (!this.throttledMap.has(cacheKey)) {
            this.throttledMap.set(
              cacheKey,
              this.createThrottledHandler(
                child.props[eventName],
                throttleTime,
                throttleOptions
              )
            );
          }

          newEventObj[eventName] = this.throttledMap.get(cacheKey);
        }
      });

      if (Object.keys(newEventObj).length > 0) {
        return React.cloneElement(child, newEventObj);
      }

      return child;
    });
  }
}